home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / gymake12.zip / TSTRING.C < prev    next >
C/C++ Source or Header  |  1988-11-18  |  4KB  |  202 lines

  1. /*
  2.  * tstring.c
  3.  *
  4.  * 88-10-01 v1.0    created by greg yachuk, placed in the public domain
  5.  * 88-10-06 v1.1    changed prerequisite list handling
  6.  * 88-11-11 v1.2    fixed some bugs and added environment variables
  7.  *
  8.  */
  9. #include <stdio.h>
  10. #include <ctype.h>
  11. #include <malloc.h>
  12. #include <string.h>
  13.  
  14. #include "tstring.h"
  15.  
  16.  
  17. char   *
  18. talloc(n)
  19. int    n;
  20. {
  21.     register char *s;
  22.  
  23.     s = malloc(n);
  24.     if (s == NULL)
  25.         terror(1, "no free memory");
  26.     return (s);
  27. }
  28.  
  29.  
  30. char   *
  31. trealloc(s, n)
  32. register char *s;
  33. int    n;
  34. {
  35.     s = realloc(s, n);
  36.     if (s == NULL)
  37.         talloc(n);    /* force an error */
  38.     return (s);
  39. }
  40.  
  41.  
  42. char   *
  43. tstrncpy(s, n)
  44. register char *s;
  45. int    n;
  46. {
  47.     s = strncpy(talloc(n+1), s, n);
  48.     s[n] = '\0';
  49.     return (s);
  50. }
  51.  
  52.  
  53. terror(n, s)
  54. int    n;
  55. char   *s;
  56. {
  57.     fputs("Make: ", stderr);
  58.     fputs(s, stderr);
  59.     if (n)
  60.         exit(n);
  61. }
  62.  
  63.  
  64. /*
  65.  * token    - take an input string and return a token each call
  66.  *        - default token delimiter characters are `isspace()'
  67.  *        - text between quotes (" and ') is a single token
  68.  *
  69.  *    called as    s = token(string, seps);
  70.  *        or    s = token(string, NULL);
  71.  *
  72.  *    followed by    s = token(NULL, seps);
  73.  *        or    s = token(NULL, NULL);
  74.  *
  75.  *    returns NULL when no more tokens are available
  76.  */
  77. char   *
  78. token(s, sep)
  79. char   *s;
  80. char   *sep;
  81. {
  82.     static char *olds = NULL;
  83.     char    quote = 0;        /* processing a quoted token */
  84.  
  85.     if (s)    olds = s;        /* we are starting all over again */
  86.  
  87.     if (!olds || !*olds)
  88.         return (NULL);        /* no tokens left */
  89.  
  90.     while (isspace(*olds) || (sep && strchr(sep, *olds)))
  91.         ++olds;            /* skip leading spaces and sep's */
  92.  
  93.     if (*olds == NULL)
  94.         return (NULL);        /* remainder is all separator's */
  95.  
  96.     s = olds;
  97.  
  98.     while (*olds)
  99.     {
  100.         if (isspace(*olds) || (sep && strchr(sep, *olds)))
  101.         {
  102.             *olds++ = '\0';    /* delimit the token */
  103.             return (s);
  104.         }
  105.         else if (*olds == '"' || *olds == '\'')
  106.         {
  107.             quote = *olds++;
  108.             while (*olds != quote && *olds)
  109.                 ++olds;    /* search for the proper quote char */
  110.             if (*olds != '\0')
  111.                 ++olds;    /* didn't hit eos, so skip quote */
  112.         }
  113.         else    ++olds;        /* otherwise, pass over char */
  114.     }
  115.  
  116.     olds = NULL;
  117.     return (s);            /* return last token */
  118. }
  119.  
  120.  
  121. /*
  122.  * tokenize    - chop a string up into an array of (char *)'s
  123.  */
  124. char  **
  125. tokenize(input)
  126. char   *input;
  127. {
  128.     char  **argv;
  129.     register int argc = 0;
  130.     register int alen;
  131.  
  132.     alen = 20;        /* good initial guess */
  133.     argv = (char **) talloc((alen + 1) * sizeof (char *));
  134.  
  135.     input = token(input, NULL);    /* use default separators */
  136.     while (input)
  137.     {
  138.         if (alen == argc)
  139.             argv = (char **) trealloc((char *) argv,
  140.                           (alen <<= 1)*sizeof (char *));
  141.         argv[argc++] = input;
  142.         input = token(NULL, NULL);
  143.     }
  144.  
  145.     argv[argc] = NULL;    /* mark end of array */
  146.  
  147.     return (argv);
  148. }
  149.  
  150.  
  151. /*
  152.  * tgets    - read input, swallowing escaped newlines as necessary
  153.  */
  154. char   *
  155. tgets(fd)
  156. FILE   *fd;
  157. {
  158.     static char *input = NULL;
  159.     static int inlen = 0;
  160.     register char *ep;
  161.     int    len;
  162.  
  163.     if (inlen == 0)
  164.         input = talloc(inlen = 162);
  165.  
  166.     input[inlen-2] = '\n';
  167.     ep = input - 1;
  168.     while ((fgets(input, inlen, fd)) != NULL)
  169.     {
  170.         for(;;)
  171.         {
  172.             while (input[inlen-2] != '\n' && input[inlen-2] != '\0')
  173.             {
  174.                 len = inlen;
  175.                 input = trealloc(input, inlen <<= 1);
  176.                 ep = &input[len-2];
  177.                 input[inlen-2] = '\n';
  178.                 fgets(ep+1, len+1, fd);
  179.             }
  180.  
  181.             while (*++ep);
  182.             *--ep = '\0';
  183.             do {
  184.                 --ep;
  185.             } while (isspace(*ep) && ep >= input);
  186.  
  187.             if (*ep == '\\' && *--ep != '\\')
  188.                 fgets(ep+1, inlen - (ep - input) - 1, fd);
  189.             else
  190.                 break;
  191.         }
  192.  
  193.         return (input);
  194.     }
  195.  
  196.     inlen = 0;
  197.     tfree(input);
  198.     input = NULL;
  199.  
  200.     return (NULL);
  201. }
  202.